#pragma once

#include <iostream>
#include <vector>
#include <string>
#include <queue>
#include <unistd.h>
#include "thread.hpp"
#include "lockGuard.hpp"
#include "log.hpp"

static int g_thread_num = 3;

template <class T>
class ThreadPool
{
public:
    // 给static void *routine(void *args)用的接口
    pthread_mutex_t *getMutex()
    {
        return &_lock;
    }
    bool isEmpty()
    {
        return _task_queue.empty();
    }
    void waitCond()
    {
        pthread_cond_wait(&_cond, &_lock);
    }
    T getTask()
    {
        T t = _task_queue.front();
        _task_queue.pop();
        return t;
    }

public:
    ThreadPool(int thread_num = g_thread_num) : _num(thread_num)
    {
        for (int i = 1; i <= _num; i++)
        {
            _threads.push_back(new Thread(i, routine, this));
        }
        pthread_mutex_init(&_lock, nullptr);
        pthread_cond_init(&_cond, nullptr);
    }
    ~ThreadPool()
    {
        for (auto &iter : _threads)
        {
            iter->start();
            delete iter;
        }
        pthread_mutex_destroy(&_lock);
        pthread_cond_destroy(&_cond);
    }

    void run()
    {
        for (auto &iter : _threads)
        {
            iter->start();
            //std::cout << iter->name() << "启动成功" << std::endl;
            logMessage(NORMAL, "%s%s", iter->name().c_str(), "启动成功");
        }
    }

    static void *routine(void *args)
    {
        ThreadData *td = (ThreadData *)args;
        ThreadPool<T> *tp = (ThreadPool<T> *)td->_args;

        while (true)
        {
            T task;
            {

                lockGuard lockguard(tp->getMutex());
                while (tp->isEmpty())
                    tp->waitCond();

                // 读取任务
                task = tp->getTask();
            }
            // 仿函数执行任务
            task(td->_name);
            // std::cout << "我是一个线程，我的名字是：" << td->_name << std::endl;
            // sleep(1);
        }
    }
    void pushTask(const T &task)
    {
        lockGuard lockguard(&_lock);
        _task_queue.push(task);
        pthread_cond_signal(&_cond);
    }

private:
    std::vector<Thread *> _threads;
    int _num; // 线程数量
    std::queue<T> _task_queue;

    pthread_mutex_t _lock;
    pthread_cond_t _cond;
};